Research question: “Rolling Stone Magazine ranked their 100 greatest musical artists of all time. At the end of 2023, how has their music endured? Are there any features or characteristics that seem to explain enduring engagement?”
The Github Repository with the project: Link
Rolling Stone’s ranking honors both the legendary rock and roll icons of the Sixties and contemporary trailblazers like Eminem. To analyse their musical styles, I utilized Spotifyr library for interacting with Spotify API. The exploration in this notebook aims to understand how rock artistry endures in the modern era and to identify which musicians from the top 100 list are still influential today. By analyzing Spotify’s data, I offer insights into the current musical landscape, which still has prominent features of the rock music.
In this project, I have looked at the following sources:
In Figure 1, we look at those 10 artists from the Rolling Stones list who had the highest number of follower count in Spotify ranking. Eminem is at the top with 80 million followers, and Queen is next with 49 million. Later in this notebook, we’ll explore why Eminem’s music is so popular.
There’s also a second group of famous artists: Guns n’ Roses, AC/DC, Michael Jackson, Metallica, and The Beatles. Each of them has a lot of followers too. Pink Floyd, Nirvana, and Tupac Shakur are in another group, each with around 18 million followers.
It’s interesting to note that Eminem was only 83rd on Rolling Stone’s list, but he’s got more Spotify followers than anyone else on the list. Only The Beatles, Michael Jackson, and Nirvana were in the top 50 of Rolling Stone’s ranking, showing the differences over a periods of time from 2011 to 2023.
In Figure 2, we look at those 10 artists from the Rolling Stones list who had the highest popularity on Spotify.Popularity is ranked by Spotify on a scale of 0 to 100. Yet again, Eminem rules the chart with a whopping popularity of 90. This is followed by Queen (similar to the followers ranking). At the next level, we have The Beatles and Elton John sharing the place with 83 as their score. There are some names which were not seen in Figure 1 like Jay-Z, Elvis Presley, Elton John and Radiohead.
In Figure 3, we look at the most occuring genres amongst all the artists in Rolling Stones list. Rock, undoubtedly comes at the first. There are other forms of Rock that appear like hard rock, album rock, classic rock, folk rok etc.
In Figure 4, we look at those genres that appeared in the list of artists with highest followers and popularity on Spotify. We find new genres like rap, glam rock, gangster rap, and hip hop. Rock and classic rock, remained evergreen in 2023 as well.
In Figure 5, we look at the 14 artists who have either the highest followers or popularity on the Spotify platform in 2023. Here, we can look at how similar one artist is to another in terms of genre. It is notable that Eminem in the sole singer in the genre Detroit Hip Hop. This novel aspect could also be attributed to his successful engagement. The genre of rap which was no where to be found amongst the top artists in Rolling Stone list, now has 3 artists (Tupac Shakur, Eminem, JayZ) An interesting aspect here is that Michael Jackson has its niche in soul and R&B, and has been one of the pop icons for all generations.
## [1] "Nirvana" "Elton John"
## [3] "Queen" "Metallica"
## [5] "Creedence Clearwater Revival"
These are the rock artists that appeared on 2023 Year-End Charts, showing that their music is still liked by people even in 2023. Link
In Figure 6, we see high danceability and energy , which is a feature of the genres in which Eminem sings. This trend matches with the more energetic sings liked by our generation.
Spotify has set their scales as:
Track being danceable. (0 to 1)
Energy of a track. (0 to 1)
Valence: the positivity or happiness of a track ( 0 to 1)
| name | popularity |
|---|---|
| Dr. Dre | 78 |
| 50 Cent | 82 |
| Snoop Dogg | 81 |
| 2Pac | 78 |
| DMX | 69 |
The table shows the top artists who are similar to Eminem.
In this section, we look at the latest playlist by Spotify in which they pick the best Rock & Alternative songs for 2023. Link
The song Now and Then appears in the playlist.
The Google Trend
shows the spike in interest for Elvis Presley. Thhis was due to a new
movie documentary made on him, which thereby increased public interest
for the artist. Episodes like these have always generated motr interest
in their music.
The dendrogram shows the albuns for the artist, and attempts to find similarities in them based on features.
The goals of this notebook were to analyze the endurance of music of the Rock Artists who appeared in the Rolling Stones 2011 in the current times. The following three conclusions summarize of what I have described in the notebook. - Conclusion 1: The Evolution of Preferences: There’s a noticeable shift in fan preferences, with rap, exemplified by the popularity of Eminem, emerging as a predominant favorite in recent times. However, it’s also evident that Rock artists maintain a significant following, underlining the genre’s sustained appeal.
Conclusion 2: Energetic and Danceable Tunes: The analysis reveals a preference for songs with high danceability and energy, a characteristic that has long been a hallmark of Rock music. This suggests that while the styles may evolve, the core elements that define Rock music continue to resonate with audiences.
Conclusion 3: Timeless Appeal of Iconic Artists: Artists like The Beatles continue to be relevant, frequently appearing in modern playlists. This enduring popularity underscores the timeless nature of their music and its ability to transcend generational boundaries.
knitr::opts_chunk$set(echo = TRUE)
library(htmlwidgets)
library(htmltools)
library(rvest)
library(tidyverse)
library(dplyr)
library(stringr)
library(RSelenium)
library(netstat)
library(httr)
library(jsonlite)
library(lubridate)
library(knitr)
library(ggplot2)
library(scales)
library(sf)
library("clipr")
library(spotifyr)
library(scales)
library(ggplot2)
library(dplyr)
library(plotly)
library(reshape2)
library(dendextend)
library(fmsb)
DiagrammeR::grViz("digraph {
graph [layout = dot, rankdir = TB]
node [shape = rectangle]
rec1 [label = 'Step 1. Scrape Titles from Rolling Stone Webpage ']
rec2 [label = 'Step 2. Get Artists ID from Spotify Website']
rec3 [label = 'Step 3. Interact with Spotify Web API']
rec4 [label = 'Step 4. Compare and Visualize Artists']
# edge definitions with the node IDs
rec1 -> rec2 -> rec3 -> rec4
}",
height = 300)
# 2. SCRAPING ROLLING STONE WEBSITE
## 2.1 Helper function
scrape_titles <- function(url, num_titles = 50){
read_html(url)%>%
html_nodes('h2')%>%
html_text()%>%
head(num_titles) %>%
tibble(Titles=.)
}
#' Scrape Titles from HTML Page
#' @param url The URL of the HTML page to scrape titles from.
#' @param num_titles The number of titles to retrieve (default is 50).
#' @return A tibble containing the scraped titles.
## 2.2 Calling Function: Combines the results
rolling_stone_ranking <- function(){
# URLs
url1 <- "https://www.rollingstone.com/music/music-lists/100-greatest-artists-147446/"
url2 <- paste0(url1,'the-band-2-88489/')
# Scrape titles from both URLs and combine into a single tibble
all_titles <- bind_rows(
scrape_titles(url1),
scrape_titles(url2)
)
return(all_titles)
}
#' Rolling Stone Artists Ranking
#' @return Combined tibble of titles from two Rolling Stone URLs.
#' @details Scrapes titles from two Rolling Stone URLs and combines into a single tibble.
## 2.3 Output: Tibble arranged in descending Order
all_artists <- rolling_stone_ranking()%>%
dplyr::arrange(-dplyr::row_number())
# 3. WORKING WITH SPOTIFY API
readRenviron("Spotify.Renviron")
clientID <- Sys.getenv("SPOTIFY_CLIENT_ID")
key <- Sys.getenv("SPOTIFY_CLIENT_SECRET")
# Set Spotify API credentials
Sys.setenv(SPOTIFY_CLIENT_ID = clientID)
Sys.setenv(SPOTIFY_CLIENT_SECRET = key)
### Acess Token
get_access_token <- function(clientID, secret) {
verification_url <- 'https://accounts.spotify.com/api/token'
auth_string <- paste0(clientID, ":", secret)
response <- httr::POST(
verification_url,
httr::accept_json(),
httr::authenticate(clientID, secret),
body = list(grant_type = 'client_credentials'),
encode = 'form',
httr::verbose()
)
return(httr::content(response)$access_token)
}
### Authorization Header
get_header<- function(token){
HeaderValue <- paste0('Bearer ', token)
return(HeaderValue)
}
#' Generate Spotify API Request Header
#' @param token Access token obtained from Spotify.
#' @return Authorization header for Spotify API requests.
access_token <- get_access_token(Sys.getenv("SPOTIFY_CLIENT_ID"),
Sys.getenv("SPOTIFY_CLIENT_SECRET"))
HeaderValue <-get_header(access_token)
## 3.2 Scraping Artist ID
# (I used this because I found the search request on API later.)
scrapeArtistsID <- function(all_artists) {
rD <- rsDriver(browser = c("firefox"), verbose = FALSE, port = netstat::free_port(random = TRUE), chromever = NULL)
driver <- rD[["client"]]
# Define XPaths for various elements
accept_cookies <- '//*[@id="onetrust-accept-btn-handler"]'
search_left_col <- "/html/body/div[4]/div/div[2]/div[1]/nav/div[1]/ul/li[2]"
search_bar <- "/html/body/div[4]/div/div[2]/div[3]/header/div[3]/div/div/form/input"
#input the name of the band
choose_artist_option <- '/html/body/div[4]/div/div[2]/div[3]/div[1]/div[2]/div[2]/div/div/div[2]/main/div[1]/div/div/div/div/div/a[4]/button/span'
choose_artist_option_2 <- '//*[@id="main"]/div/div[2]/div[3]/div[1]/div[2]/div[2]/div/div/div[2]/main/div[1]/div/div/div/div/div/a[2]/button/span'
top_result_card <- "/html/body/div[4]/div/div[2]/div[3]/div[1]/div[2]/div[2]/div/div/div[2]/main/div[2]/div/div/div/div[1]/div[1]"
hamburger_menu <- "/html/body/div[4]/div/div[2]/div[3]/div[1]/div[2]/div[2]/div/div/div[2]/main/section/div/div[2]/div[2]/div[4]/div/div/div/div/button[2]"
click_share_button <- "/html/body/div[24]/div/ul/li[4]"
copy_link_to_artist <- "/html/body/div[24]/div/ul/li[4]/div/ul/li[1]/button"
# Vector to store Spotify IDs
spotify_ids <- vector("list", length = length(all_artists))
url <- "https://open.spotify.com/search"
# Navigate to Spotify search page
driver$navigate(url)
Sys.sleep(1)
# Accept cookies
opener <- driver$findElement(using ="xpath", value = accept_cookies)
opener$clickElement()
Sys.sleep(1)
for (i in seq_along(all_artists$Titles)) {
search_left <- driver$findElement(using="xpath", value = search_left_col)
search_left$clickElement()
#Input Artist Name
search_artist <- driver$findElement(using = "xpath", value = search_bar)
search_artist$sendKeysToElement(list(all_artists$Titles[i]))
Sys.sleep(2)
button_xpath <- "/html/body/div[4]/div/div[2]/div[3]/div[1]/div[2]/div[2]/div/div/div[2]/main/div[1]/div/div/div/div/div/a[4]/button/span"
button_element <- driver$findElement(using = "xpath", value = button_xpath)
button_element$clickElement()
# Selecting
top_result <- driver$findElement(using="xpath", value = top_result_card)
top_result$clickElement()
Sys.sleep(1)
Sys.sleep(1)
# hamburger_Menu
hamburger <- driver$findElement(using="xpath", value = hamburger_menu)
hamburger$clickElement()
Sys.sleep(1)
# Right click on card
click_share <- driver$findElement(using="xpath", value = click_share_button)
click_share$clickElement()
Sys.sleep(1)
# click copy_link_to_artist
copy_link <- driver$findElement(using="xpath", value = copy_link_to_artist)
copy_link$clickElement()
# Read the Spotify ID from clipboard
spotify_ids[[i]] <- read_clip()
}
# Close the browser
driver$close()
# Create a dataframe with artist names and Spotify IDs
result_df <- data.frame(Artist = artists,
SpotifyID = unlist(spotify_ids),
stringsAsFactors = FALSE)
return(result_df)
}
#scrapeArtistsID(all_artists)
# result_dataframe <- scrapeArtistsID(all_artists)
# Save the dataframe to a CSV file
# write.csv(result_dataframe, "Top_100_Artists.csv", row.names = FALSE)
fetch_artists_details = function(){
all_100_artists <- read.csv('Top_100_Artists.csv')
get_artist_ENDPOINT <- "https://api.spotify.com/v1/artists/"
access_token <- get_access_token(Sys.getenv("SPOTIFY_CLIENT_ID"),
Sys.getenv("SPOTIFY_CLIENT_SECRET"))
HeaderValue <-get_header(access_token)
# Initialize vectors to store data
Followers <- numeric(length(all_100_artists$SpotifyID))
Popularity <- numeric(length(all_100_artists$SpotifyID))
for (i in seq_along(all_100_artists$SpotifyID)) {
artist_ID <- all_100_artists$SpotifyID[i]
URI <- paste0(get_artist_ENDPOINT, artist_ID)
response2 <- GET(url = URI, add_headers(Authorization = HeaderValue))
Artist <- content(response2)
# Store data in vectors
Followers[i] <- Artist$followers$total
Popularity[i] <- Artist$popularity
updated_artists_data <- cbind(all_100_artists, Followers, Popularity)
return (updated_artists_data)
}
}
# Writing the data
# all_100_artists <- fetch_artists_details()
# write.csv(all_100_artists, "Top_100_Artists.csv", row.names = FALSE)
all_100_artists <- read.csv("Top_100_Artists.csv")
# Select the top 10 artists based on Followers
top_followers <- all_100_artists %>%
arrange(desc(Followers)) %>%
select(Artist, Followers) %>%
head(10)
# Select the top 10 artists based on Popularity
top_popularity <- all_100_artists %>%
arrange(desc(Popularity)) %>%
select(Artist, Popularity) %>%
head(10)
# Function to create a Plotly interactive chart
create_interactive_chart <- function(data, y_column, title) {
tooltip_text <- paste(format(data[y_column], big.mark = ",", scientific = FALSE))
p <- ggplot(data, aes_string(x = "Artist", y = y_column, label = "Artist", text = tooltip_text)) +
geom_point(aes_string(size = y_column), color = "blue", alpha = 0.5) +
geom_text(aes(label = Artist), vjust = 1, hjust = 1.5) +
labs(title = title, y = y_column, x = "Artist") +
theme_minimal()+
theme(axis.text.x = element_blank())+
scale_y_continuous(labels = label_comma()) # Format y-axis labels
# Convert to Plotly with custom tooltip
ggplotly(p, tooltip = "text")
}
# Creates interactive chart for followers
plot_followers <- create_interactive_chart(top_followers, "Followers", "Fig 1: Top Artists by Followers")
# Creates interactive chart for popularity
plot_popularity <- create_interactive_chart(top_popularity, "Popularity", "Fig 2:Top Artists by Popularity")
plot_followers
plot_popularity
# Extracting Genres list
# Function to retrieve genres and convert them into a single string
get_genres_as_string <- function(spotify_id) {
artist_info <- get_artist(spotify_id)
if (length(artist_info$genres) > 0) {
return(paste(artist_info$genres, collapse = ", "))
} else {
return(NA) # Return NA if there are no genres
}
}
# Apply the function to each row in the data frame and create a new column for genres
all_100_artists$Genres <- sapply(all_100_artists$SpotifyID,
get_genres_as_string)
# Assuming 'data' is your data frame and 'Genres' is the column with genres
# Splitting the genres and creating a frequency table
genre_list <- strsplit(all_100_artists$Genres, ", ")
genre_table <- table(unlist(genre_list))
# Creating a data frame for the top 10 genres
top_genres <- head(sort(genre_table, decreasing = TRUE), 10)
top_genres_df <- data.frame(Genre = names(top_genres), Frequency = as.numeric(top_genres))
# Bar Chart for Top 10 Music Genres acc. to Rolling Stones
bar_chart_object <- ggplot(top_genres_df, aes(x = reorder(Genre, Frequency), y = Frequency)) +
geom_bar(stat = "identity", fill = "steelblue") +
coord_flip() + # Flips the coordinates to make horizontal bars
theme_minimal() +
labs(title = "Fig 3: Top 10 Music Genres (Rolling Stones)", x = "Genre", y = "Frequency")
# Convert to a plotly object for interactive features
genres_bar_chart <- ggplotly(bar_chart_object)
# Display the plotly object
genres_bar_chart
# Function to fetch genres for a given artist
get_genres_for_artist <- function(artist_name, all_artists_df) {
genres <- all_artists_df$Genres[all_artists_df$Artist == artist_name]
if (length(genres) > 0) {
return(paste(unique(genres), collapse = ", "))
} else {
return(NA)
}
}
# Top artists by Followers and Popularity
top_artists_2023 <- unique(c(top_followers$Artist, top_popularity$Artist))
# Create a new dataframe for top artists and their genres
top_artists_genres_df <- data.frame(Artist = top_artists_2023,
Genres = sapply(top_artists_2023, get_genres_for_artist, all_artists_df = all_100_artists),
stringsAsFactors = FALSE)
# Unlist and trim genres to ensure clean data
trimmed_genres <- trimws(unlist(strsplit(top_artists_genres_df$Genres, ",\\s*")))
# Count frequencies of genres
genre_frequency <- table(trimmed_genres)
# Sort and select top 10 genres
top_genres <- sort(genre_frequency, decreasing = TRUE)[1:10]
# Convert to dataframe
top_genres_df <- data.frame(Genre = names(top_genres), Frequency = as.numeric(top_genres))
create_top_genres_visualization <- function(all_100_artists, top_followers, top_popularity) {
# Bar Chart for Top 10 Genres among Top Artists
ggplot_object <- ggplot(top_genres_df, aes(x = reorder(Genre, Frequency), y = Frequency, text = paste("Genre:", Genre, "<br>Frequency:", Frequency))) +
geom_bar(stat = "identity", fill = "steelblue") +
coord_flip() + # Flips the coordinates to make horizontal bars
theme_minimal() +
labs(title = "Fig 4: Top 10 Music Genres (2023 Spotify)", x = "Genre", y = "Frequency")
# Convert to a plotly object with customized tooltip
plotly_object <- ggplotly(ggplot_object, tooltip = "text")
# Return the plotly object
return(plotly_object)
}
# Usage of the function
Spotify_genres_chart <- create_top_genres_visualization(all_100_artists, top_followers, top_popularity)
Spotify_genres_chart
# Create a long format data frame suitable for a heatmap
long_data <- top_artists_genres_df %>%
mutate(Genre = strsplit(Genres, ",\\s*")) %>%
unnest(Genre) %>%
count(Artist, Genre)
# Create a wide format data suitable for the heatmap
wide_data <- dcast(long_data, Artist ~ Genre, value.var = "n", fill = 0)
# Melt the data for ggplot
melted_data <- melt(wide_data, id.vars = 'Artist')
# Heatmap plot
ggplot_object <- ggplot(melted_data, aes(x = Artist, y = variable)) +
geom_tile(aes(fill = value), color = "white") +
scale_fill_gradient(low = "white", high = "steelblue") +
labs(title = "Fig 5: Artist-Genre Association Heatmap")+
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1, size = 7), # Rotate and adjust x-axis labels
axis.title.x = element_blank(),
axis.title.y = element_blank(),
legend.position = "none")
# Convert to a plotly object for interactivity
genres_heatmap <- ggplotly(ggplot_object)
# Display the plotly object
genres_heatmap
URL <- "https://www.billboard.com/charts/year-end/2023/top-rock-artists/"
billboard_artists <- read_html(URL) %>%
html_nodes('#title-of-a-story') %>%
html_text() %>%
head(25) %>%
str_trim() %>% # Remove leading and trailing whitespace
gsub("[\r\n\t]", "", .) %>% # Remove all occurrences of \r, \n, and \t
tibble(Artists = .)
# Finding matching artists
matching_artists <- all_100_artists[all_100_artists$Artist %in% billboard_artists$Artists, ]
print(matching_artists$Artist)
# Steps
## 1. Fetch Top Tracks of the Artist
## 2. Select Top 5 Tracks Based on Popularity
## 3. Retrieve Audio Features for Each Track
## 4. Compile the Data into a DataFrame
## 5. Explore similar artists to Eminem
plot_audio_features <- function(artist_id, graph_title){
# Fetch top tracks of the artist
top_tracks <- get_artist_top_tracks(artist_id)
# Select top 5 tracks based on popularity
top_5_tracks <- head(top_tracks[order(-top_tracks$popularity), ], 5)
track_details <- data.frame(
valence = numeric(),
danceability = numeric(),
energy = numeric()
)
for (track in top_5_tracks$id) {
features <- get_track_audio_features(track)
track_details <- rbind(track_details, data.frame(
name = top_tracks$name[top_tracks$id == track],
valence = features$valence,
danceability = features$danceability,
energy = features$energy
))
}
# Melt the data for ggplot
long_data <- reshape2::melt(track_details, id.vars = 'name')
# Creating a ggplot
ggplot(long_data, aes(x = name, y = value, fill = variable)) +
geom_bar(stat = "identity", position = position_dodge()) +
theme_minimal() +
labs(title = graph_title, x = "Track", y = "Value") +
scale_fill_brewer(palette = "Set1") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
}
# Artist's Spotify ID
eminem_id <- "7dGJo4pcD2V6oG8kP0tJRR"
plot_audio_features(eminem_id, "Fig 6: Audio Features of Top 5 Eminem songs")
# Retrieve similar artists to Eminem
similar_artists_to_eminem <- get_related_artists(eminem_id)%>%
head(5)
# Display the names of similar artists
knitr::kable(similar_artists_to_eminem[, c("name", "popularity")])
# Playlist ID
playlist_id <- "37i9dQZF1DX8YNmLOBjUmx"
# Fetch tracks from the playlist
playlist_tracks <- get_playlist_tracks(playlist_id)
# Select top 5 tracks based on popularity
top_5_tracks <- head(playlist_tracks[order(-playlist_tracks$track.popularity), ], 5)
get_top_albums <- function(artist_name) {
# Get artist audio features
artist_data <- spotifyr::get_artist_audio_features(artist_name)
# Select numeric columns and album_name
artist_data <- artist_data %>%
select_if(is.numeric) %>%
bind_cols(artist_data %>% select(album_name))
# Clean album names
artist_data <- artist_data %>%
mutate(album_name = gsub(" *\\(.*?\\) *| *\\[.*?\\] *", "", album_name))
# Group by album_name and calculate the mean for numeric columns
artist_data <- artist_data %>%
group_by(album_name) %>%
summarise_if(is.numeric, mean, na.rm = TRUE) %>%
ungroup() %>%
column_to_rownames("album_name") %>%
as.data.frame()
# Create dendrogram
top_dend <- as.dendrogram(hclust(dist(top_albums))) %>%
color_branches(k = 8) %>%
color_labels(k = 8)
# Plot circlize dendrogram
circlize_dendrogram(top_dend, labels_track_height = 0.3, dend_track_height = 0.3)
return(top_albums)
}
get_top_songs <- function(artist_name) {
# Get top tracks of the artist
artist_tracks <- spotifyr::get_artist_audio_features(artist_name)
# Select the desired columns and order by popularity
top_tracks <- artist_tracks %>%
select(track_name, album_name) %>%
head(10)
return(top_tracks)
}
beatles <- spotifyr::get_artist_audio_features('The Beatles')
beatles <- beatles%>%
select_if(is.numeric)%>%
bind_cols(beatles%>% select(album_name))%>%
mutate(album_name = gsub(" *\\(.*?\\) *| *\\[.*?\\] *", "", album_name)) %>%
group_by(album_name)%>%
summarise_if(is.numeric, mean, na.rm=TRUE)%>%
ungroup() %>%
#select(-album_popularity)%>%
column_to_rownames("album_name")%>%
as.data.frame()
top_dend <- as.dendrogram(hclust(dist(beatles)))%>%
color_branches(k=8)%>%
color_labels(k=8)
circlize_dendrogram(top_dend, labels_track_height = 0.3, dend_track_height = .3)
bob_dylan <- spotifyr::get_artist_audio_features('Bob Dylan')
bob_dylan <- bob_dylan%>%
select_if(is.numeric)%>%
bind_cols(bob_dylan%>% select(album_name))%>%
mutate(album_name = gsub(" *\\(.*?\\) *| *\\[.*?\\] *", "", album_name)) %>%
group_by(album_name)%>%
summarise_if(is.numeric, mean, na.rm=TRUE)%>%
ungroup() %>%
#select(-album_popularity)%>%
column_to_rownames("album_name")%>%
as.data.frame()
top_dend <- as.dendrogram(hclust(dist(bob_dylan)))%>%
color_branches(k=8)%>%
color_labels(k=8)
circlize_dendrogram(top_dend, labels_track_height = 0.3, dend_track_height = .3)
#June 2022 release of Baz Luhrmann's biopic of Elvis Presley
elvis <- spotifyr::get_artist_audio_features('Elvis Presley')
elvis <- elvis%>%
select_if(is.numeric)%>%
bind_cols(elvis%>% select(album_name))%>%
mutate(album_name = gsub(" *\\(.*?\\) *| *\\[.*?\\] *", "", album_name)) %>%
group_by(album_name)%>%
summarise_if(is.numeric, mean, na.rm=TRUE)%>%
ungroup() %>%
#select(-album_popularity)%>%
column_to_rownames("album_name")%>%
as.data.frame()
top_dend <- as.dendrogram(hclust(dist(elvis)))%>%
color_branches(k=8)%>%
color_labels(k=8)
circlize_dendrogram(top_dend, labels_track_height = 0.3, dend_track_height = .3)
rolling_stones <- spotifyr::get_artist_audio_features('Rolling Stones')
rolling_stones <- rolling_stones%>%
select_if(is.numeric)%>%
bind_cols(rolling_stones%>% select(album_name))%>%
mutate(album_name = gsub(" *\\(.*?\\) *| *\\[.*?\\] *", "", album_name))%>%
group_by(album_name)%>%
summarise_if(is.numeric, mean, na.rm=TRUE)%>%
ungroup() %>%
#select(-album_popularity)%>%
column_to_rownames("album_name")%>%
as.data.frame()
top_dend <- as.dendrogram(hclust(dist(rolling_stones)))%>%
color_branches(k=8)%>%
color_labels(k=8)
circlize_dendrogram(top_dend, labels_track_height = 0.3, dend_track_height = .3)
# this chunk generates the complete code appendix.
# eval=FALSE tells R not to run (``evaluate'') the code here (it was already run before).